/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package core;

import core.ErrorLogger;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import util.FilesUtil;

/**
 *
 * @author Marcin
 */
public class Config {
    Properties properties;
    File dirLog;
    
    private static final byte[] SALT = {
        (byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12,
        (byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12,
    };
    private static final char[] PASSWORD = "enfldsgbnlsngdlksdsgm".toCharArray();
    
    public Config()
    {
        properties = new Properties();
        dirLog = new FilesUtil().createDir("config");
    }
    public void addProperty(String key,String value)
    {
        if(key.compareTo("password") == 0)
        {
            try {
                value = encrypt(value);
            } catch (    NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException ex) {
                ErrorLogger.getInstance().log("Błąd szyfrowania hasła", false, null);
            }
        }
        properties.put(key, value);
    }
    public void modifyProperty(String key,String value)
    {
        properties.setProperty(key, value);
    }
    public Object getProperty(String key)
    {
        if(key.compareTo("password") == 0)
        {
            try {
                return decrypt(properties.getProperty(key));
            } catch (    GeneralSecurityException | IOException ex) {
                Logger.getLogger(Config.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return properties.getProperty(key);
    }
    public boolean loadConfig()
    {
        try {
            properties.load(new FileInputStream(dirLog.getPath() + "\\config.properties"));
        } catch (IOException ex) {
            ErrorLogger.getInstance().log("Bład wczytawania pliku konfiguracyjnego", false, null);
            return false;
        }
        return true;
    }
    public boolean saveConfig()
    {
        try {
            properties.store(new FileOutputStream(dirLog.getPath() + "\\config.properties"),null);
        } catch (IOException ex) {
            ErrorLogger.getInstance().log("Bład zapisywania pliku konfiguracyjnego", false, null);
            return false;
        }
        return true;        
    }
    
    private static String encrypt(String property) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
        SecretKey key = keyFactory.generateSecret(new PBEKeySpec(PASSWORD));
        Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
        pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(SALT, 20));
        return base64Encode(pbeCipher.doFinal(property.getBytes()));
    }

    private static String base64Encode(byte[] bytes) {
        // NB: This class is internal, and you probably should use another impl
        return new BASE64Encoder().encode(bytes);
    }

    private static String decrypt(String property) throws GeneralSecurityException, IOException {
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
        SecretKey key = keyFactory.generateSecret(new PBEKeySpec(PASSWORD));
        Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
        pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(SALT, 20));
        return new String(pbeCipher.doFinal(base64Decode(property)));
    }

    private static byte[] base64Decode(String property) throws IOException {
        // NB: This class is internal, and you probably should use another impl
        return new BASE64Decoder().decodeBuffer(property);
    }
}
